import {
  BaseComponent, getHistory, udp, $WorkFlow, message, getCurrentWindow, getUIUpdater, updateAmisLayout, type IObject
} from '@cscec/udp-ui';
import { type ICtx, initProviderValue } from './context';
import type { IBaseRef, ICustomHooks, IBasePageInstance } from './interface';
import { schemaUtil } from '@/components/editor/util';

/**
 * 自定义表单基础类
 */
export class BaseCustom<P extends IBaseRef, PageInstance> extends BaseComponent<any, { providerValue: ICtx<PageInstance> }, P, ICustomHooks> implements IBasePageInstance {
  protected readonly isList: boolean = false;

  protected nextRoute: string = '';

  protected unList: Function[] = [];

  constructor(props: any, nextRoute: string, isList: boolean) {
    super(props);
    this.nextRoute = nextRoute;
    this.isList = isList;
    this.state = {
      providerValue: initProviderValue<PageInstance>(this as any, nextRoute),
    };
    // function getJsTpl() {
    //   return `$udp.AllReady(function () {
    //       console.log('detail Ready');
    //   }, function () {
    //       console.log('list Ready');
    //       $udp.request.on('request', function(url, options){
    //         //最终发送请求前的url和options
    //         return {
    //           url: url,
    //           options
    //         }
    //       });
    //       $udp.request.on('response', function(response, requestOptions, rawResponse){
    //         //接收到的response，请求的options，原始的response
    //         console.log('[debug] response:', response, requestOptions, rawResponse);
    //         return response;
    //       });
    //   });`;
    // }
    // this.unList.push(schemaUtil.loadJsContent(getJsTpl()));
    this.unList.push(schemaUtil.loadJsContent(this.props.jsInfo));
    // 通知二开脚本加载完成，二开钩子准备就绪
    this.observer.prevNotify(null, 'onScriptLoad');
  }

  getLayout = () => {
    return this.state.providerValue.uiInfo;
  };

  getHistory() {
    return getHistory();
  }

  getCapacity(){
    return this.props.capacity || {};
  }

  getPublicProperty() {
    return this.props.publicProperty || {};
  }

  getBillNoRule() {
    return this.props.billNoRule || [];
  }

  getMicroServiceName() {
    return this.props.microServiceName || 'engine';
  }

  /**
   * 当前业务主键
   */
  getBusKey() {
    return 'id';
  }

  /**
   * 获取组件实例的api
   */
  getCmpApi(id: string) {
    return udp.getCmpApi(`${this.busType}_${id}`);
  }

  /**
   * 获取工作流相关Api
   */
  getWorkFlow() {
    return $WorkFlow;
  }

  componentWillUnmount(): void {
    this.unList.forEach((un) => un?.());
    this.unList = [];
  }

  /**
   * 申请去审
   * @param records 
   */
  async applyForReview(records: IObject | Array<IObject>): Promise<[Boolean, any]> {
    const record = udp.isArray(records) ? records[0] : records;
    try {
      //0|未送审;1处理中;2|结束;3终止
      const wfFlg = Number(record.wf_flg);
      const appStatus = Number(record.app_status);
      if (!(wfFlg === 2 && appStatus === 1)) {
        message.warn('单据未审批通过，不支持去审！');
        return [false, ''];
      }

      // 获取内置钩子
      const hooks = await this.createHooks();
      const defaultParams = {
        bizCode: this.busType,
        dataId: record[this.getBusKey()],
      };
      const hookReturn = await hooks.transferStartFlowParams?.({ record, defaultParams, type: 1 });
      if (hookReturn?.cancel) {
        return [false, ''];
      }
      const result = await $WorkFlow.startFlow({
        ...defaultParams,
        orgNo: record.orgNo || record.org_no,
        processType: "cancelApprovalProcess",
        formApprovalUserNo: udp.getUser().userNo,
        ...hookReturn?.params
      });
      return [true, result];
    } catch (e) {
      return [false, e];
    }
  }

  /**
   * 发起审批流
   * @param records
   */
  async startFlow(records: IObject | Array<IObject>): Promise<[Boolean, any]> {
    if (udp.isArray(records) && records.length > 1) {
      return await this.startBatchFlow(records);
    }
    const record = udp.isArray(records) ? records[0] : records;
    try {
      const wfFlg = Number(record.wf_flg);
      if ([1, 2].includes(wfFlg)) {
        message.warn('单据已经送审！');
        return [false, ''];
      }

      if (!this.isList) {
        // 明细页面需要先保存再送审
        const keyCode = await (this as any).saveData();
        if (keyCode) {
          record[this.getBusKey()] = keyCode;
        } else {
          return [false, ''];
        }
      }
      // 获取内置钩子
      const hooks = await this.createHooks();
      const defaultParams = {
        bizCode: this.busType,
        dataId: record[this.getBusKey()],
      };
      const hookReturn = await hooks.transferStartFlowParams?.({ record, defaultParams, type: 0 });
      if (hookReturn?.cancel) {
        return [false, ''];
      }
      const result = await $WorkFlow.startFlow({ ...defaultParams, orgNo: record.orgNo || record.org_no, ...hookReturn?.params });
      return [true, result];
    } catch (e) {
      return [false, e];
    }
  }

  /**
   * 批量送审
   * @param records 
   */
  async startBatchFlow(records): Promise<[Boolean, any]> {
    const busKey = this.getBusKey();
    // 获取内置钩子
    const hooks = await this.createHooks();
    const defaultParams = {
      bizCode: this.busType
    };
    const hookReturn = await hooks.transferStartFlowParams?.({ record: records, defaultParams, type: 0 });
    if (hookReturn?.cancel) {
      return [false, ''];
    }
    await $WorkFlow.batchStartFlow({ bizCode: this.busType, bacthFlowList: records.map(r => ({ dataId: r[busKey], orgId: r.orgId || r.org_id })), ...hookReturn?.params });
    return [true, ""];
  }

  getGlobalState = () => {
    const { layout, busType, extendProperty, layoutConfig } = getCurrentWindow('ui_layout_config') || {};
    return {
      layout, layoutConfig, busType,
      billNoRule: extendProperty?.billNoRule,
      attachmentProperty: extendProperty?.attachmentProperty
    };
  };

  updateUI(updater) {
    this.state.providerValue.updateUI(() => {
      const { layout } = getUIUpdater(getCurrentWindow('ui_layout_config').layout)(updater);
      getCurrentWindow('ui_layout_config').layout = layout;
      return updateAmisLayout(this.getLayout(), layout);
    });
  }
}